/*
 * Created on 28 janv. 2007
 */
package fr.mywiki.business.profil;

import java.util.ArrayList;
import java.util.Collection;
import java.util.HashSet;
import java.util.Hashtable;
import java.util.List;
import java.util.Locale;

import fr.mywiki.business.navigation.SpacesList;
import fr.mywiki.business.resources.ResourceManager;


/**
 * This class deals with the different profiles.
 * 
 * @author Thomas
 */
public class ProfileManager {
	/** Instance of the manager, in order to limit the  */
	private static ProfileManager instance;
	
	/** A hashtable containing the different profiles */
	private Hashtable profiles;
	
	/** Private constructor */
	private ProfileManager() {
		profiles = new Hashtable();
	}
	
	/**
	 * Gets the current instance of the manager. If the instance does not exist,
	 * it is created.
	 */
	public static ProfileManager getInstance() {
		if (instance == null) {
			instance = new ProfileManager();
		}
		return instance;
	}
	
	/**
	 * Searches and returns the desired profile. If the profile is contained in
	 * <code>profiles</code>, then it is returned. Otherwise, the profile is
	 * loaded in memory, put into the <code>profiles</code> table and
	 * returned.
	 * 
	 * @param name the name of the profile.
	 * @return the correspondant <code>Profile</code> object.
	 */
	public Profile getProfile(Long id) {
		Profile profile = (Profile) profiles.get(id);
		if(profile == null)
			profile = loadProfile(id);
		return profile;
	}
	
	/**
	 * Loads the desired profile into the profiles Hashtable.
	 * 
	 * @param id Long identifier of the profile.
	 * @return the loaded profile
	 */
	private Profile loadProfile(Long id) {
		Profile profile = null;
		if(Profile.ANONYMOUS_PROFILE_ID.equals(id)) {
			profile = Profile.ANONYMOUS;
		} else if(Profile.ADMIN_PROFILE_ID.equals(id)) {
			profile = Profile.ADMIN;
		} else if(Profile.AUTHOR_PROFILE_ID.equals(id)) {
			profile = Profile.AUTHOR;
		}
		
		if(profile != null)
			profiles.put(id, profile);
		
		return profile;
	}
	
	/**
	 * Returns the spaces list associated with the profile whose identifier is
	 * given in parameter.
	 * 
	 * @param profilId the identifier of the profile.
	 * @return a <code>SpacesList</code> object.
	 */
	public SpacesList getSpaces(Long profilId) {
		return getProfile(profilId).getSpaces();
	}
	
	/**
	 * Returns all the profiles in a single collection.
	 * 
	 * @return a <code>Collection</code> of <code>Profile</code> objects.
	 */
	public Collection getProfiles() {
		HashSet set = new HashSet();
		set.add(getProfile(Profile.ANONYMOUS_PROFILE_ID));
		set.add(getProfile(Profile.ADMIN_PROFILE_ID));
		set.add(getProfile(Profile.AUTHOR_PROFILE_ID));
		return set;
	}
	
	/**
	 * Returns all the profiles an account can have when being created/edited.
	 * The profiles are ordered by increasing <i>power</i> in the application.
	 * The names of the profiles are translated.
	 * 
	 * @return a <code>List</code> of <code>Profile</code> objects.
	 */
	public List getOrderedAccountProfiles(Locale locale) {
		ArrayList list = new ArrayList();

		Profile profile = getProfile(Profile.AUTHOR_PROFILE_ID);
		profile.setName(ResourceManager.getSpecific(profile.getKey(),locale));
		list.add(profile);
		
		profile = getProfile(Profile.ADMIN_PROFILE_ID);
		profile.setName(ResourceManager.getSpecific(profile.getKey(),locale));
		list.add(getProfile(Profile.ADMIN_PROFILE_ID));

		return list;
	}
	
	/**
	 * Returns the translated name of the profile.
	 * 
	 * @param profile the profile
	 * @return a String
	 */
	public String getProfileName(Profile profile) {
		String profId = profile.getId().toString();
		return ResourceManager.getSpecific("profile." + profId, Locale.ENGLISH);
	}
}
